﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.WindowsMobile.PocketOutlook;
using System.Windows.Forms;
using System.Reflection;
using System.Threading;

namespace PimImporter
{
    internal class Importer
    {
        private string pathFile = null;
        private OutlookSession session;
        private bool firstLineHeader;
        private static FrmLoad load = null;

        internal Importer(string pathFile, bool firstLineHeader)
        {
            if (!File.Exists(pathFile))
            {
                throw new FileNotFoundException("File doesn't exists");
            }
            this.pathFile = pathFile;
            this.firstLineHeader = firstLineHeader;
            session = new OutlookSession();
        }

        internal int[] Import()
        {
            try
            {
                if (pathFile == null)
                {
                    throw new FileNotFoundException("Choose a file to import");
                }
                int n = 0;
                int err = 0;
                using (CsvReader reader = new CsvReader(pathFile, firstLineHeader))
                {
                    List<string> headers = null;
                    FrmMapping mapp;
                    Dictionary<string, int> listMapp = new Dictionary<string, int>();
                    if (firstLineHeader)
                    {
                        headers = reader.GetHeaders();
                        mapp = new FrmMapping(headers, -1, reader, ref listMapp);
                    }
                    else
                    {
                        mapp = new FrmMapping(headers, reader.GetColumnsNumber(), reader, ref listMapp);
                    }
                    if (mapp.ShowDialog() != DialogResult.OK)
                    {
                        return new int[] { -1, 0 };
                    }
                    Thread t = new Thread(new ThreadStart(Importer.Loading));
                    t.Start();
                    int maxRecord = reader.GetRecordsLen();
                    load.SetBar(maxRecord, 0);
                    int recordNum = 0;
                    while (!reader.EndOfStream)
                    {
                        string[] line = null;
                        try
                        {
                            line = reader.ReadRecord();
                        }
                        catch (Exception ex)
                        {
                            err++;
                            Def.LogErr(ex, "Error at record line N# " + recordNum);
                            continue;
                        }
                        recordNum++;
                        Contact contact = new Contact();
                        Type cont = contact.GetType();
                        foreach (var m in listMapp)
                        {
                            if (line[m.Value] != "")
                            {
                                try
                                {
                                    if (m.Key == "Anniversary" || m.Key == "Birthday")
                                    {
                                        cont.GetProperty(m.Key).SetValue(contact, Def.GetDate(line[m.Value]), null);
                                    }
                                    else if (m.Key == "WebPage")
                                    {
                                        cont.GetProperty(m.Key).SetValue(contact, new Uri(line[m.Value]), null);
                                    }
                                    else
                                    {
                                        cont.GetProperty(m.Key).SetValue(contact, line[m.Value], null);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    err++;
                                    Def.LogErr(ex, "Error at record line N# " + recordNum + "\r\nProperty: " + m.Key + "\r\nValue: " + line[m.Value]);
                                }
                            }
                        }
                        session.Contacts.Items.Add(contact);
                        n++;
                        load.SetBar(maxRecord, n);
                    }
                }
                return new int[] { n, err };
            }
            finally
            {
                if (load != null && !load.IsDisposed)
                {
                    load.CloseForm();
                }
            }
        }

        private static void Loading()
        {
            load = new FrmLoad("Import contacts");
            if (!load.IsDisposed)
            {
                load.ShowDialog();
            }
        }
    }
}
